﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.IO;
using System.Text.RegularExpressions;
using Vit.Common.Extensions;
using VitData = Vit.Web.DataAnnotations;

namespace Vit.CMS.Data
{
    [MetadataType(typeof(PageInfoMetaData))]
    public class PageInfo : Vit.Common.IStringSerializable
    {
        public string Name { get; set; }
        public string Title { get; set; }
        public string MetaKeywords { get; set; }
        public string MetaDescription { get; set; }

        public ControlLoaderInfo DesignLayout { get; set; }
        public ControlLoaderInfo DesignSkin { get; set; }

        public string Layout { get; set; }
        public string Skin { get; set; }
        public string PageTemplate { get; set; }

        public string Content { get; set; }
        public string FilePath { get; set; }

        #region IStringSerializable Members

        public string Serialize()
        {
            string metas = "";
            if (!string.IsNullOrEmpty(MetaKeywords))
                metas += string.Format("<meta name=\"keywords\" content=\"{0}\"/>\r\n", MetaKeywords);
            if (!string.IsNullOrEmpty(MetaDescription))
                metas += string.Format("<meta name=\"description\" content=\"{0}\"/>\r\n", MetaKeywords);

            string skin = "";
            if (DesignSkin != null)
            {
                DesignSkin.Indent = 1;
                skin = DesignSkin.Serialize();
            }

            string body = "";
            if (DesignLayout != null)
            {
                DesignLayout.Indent = 1;
                body = DesignLayout.Serialize();
            }

            string html = string.Format(@"<%@ Page Language=""C#"" MasterPageFile=""~/Views/Shared/Site.Master"" Inherits=""System.Web.Mvc.ViewPage"" %>

<asp:Content ID=""pageTitle"" ContentPlaceHolderID=""TitleContent"" runat=""server"">
{0}
</asp:Content>
<asp:Content ID=""headContentBegin"" ContentPlaceHolderID=""HeadContentBegin"" runat=""server"">
{1}
</asp:Content>
<asp:Content ID=""headContentEnd"" ContentPlaceHolderID=""HeadContentEnd"" runat=""server"">
{2}
</asp:Content>
<asp:Content ID=""bodyContent"" ContentPlaceHolderID=""BodyContent"" runat=""server"">
{3}
</asp:Content>
", Title, metas, skin, body);

            return html;
        }

        public void Deserialize(string value)
        {
            this.Content = value;
            if (string.IsNullOrEmpty(this.Content) && !string.IsNullOrEmpty(FilePath))
            {
                FileInfo file = new FileInfo(FilePath);
                if (file.Exists)
                {
                    StreamReader sr = new StreamReader(file.FullName);
                    this.Content = sr.ReadToEnd();
                    this.Name = file.Name.Replace(file.Extension, "");
                    sr.Close();
                }
            }

            if (string.IsNullOrEmpty(this.Content))
                return;

            string contentPattern = @"<asp:Content[^<>]*ID\s*=\s*""{0}""[^<>]*?((/>)|(>(?<content>(.|\r|\n)*?)</asp:Content>))";
            string pattern = string.Format(contentPattern, "pageTitle");
            Match match = null;
            RegexOptions options = RegexOptions.IgnoreCase | RegexOptions.Multiline;

            match = Regex.Match(this.Content, pattern, options);
            if (match.Success)
                this.Title = match.Groups["content"].Value.Trim();

            pattern = string.Format(contentPattern, "headContentBegin");
            match = Regex.Match(this.Content, pattern, options);
            if (match.Success)
            {
                string metas = match.Groups["content"].Value.Trim();

                pattern = @"<meta\s*name=""keywords""\s*content=""(?<content>[^<>]*)""\s*/?>";
                match = Regex.Match(metas, pattern, options);
                if (match.Success)
                    this.MetaKeywords = match.Groups["content"].Value.Trim();

                pattern = @"<meta\s*name=""description""\s*content=""(?<content>[^<>]*)""\s*/?>";
                match = Regex.Match(metas, pattern, options);
                if (match.Success)
                    this.MetaDescription = match.Groups["content"].Value.Trim();
            }

            pattern = string.Format(contentPattern, "headContentEnd");
            match = Regex.Match(this.Content, pattern, options);
            if (match.Success)
            {
                this.DesignSkin = new ControlLoaderInfo(this, this);
                this.DesignSkin.Deserialize(match.Groups["content"].Value.Trim());
                pattern = @"~/Layouts/[^<>/]+/Skins/(?<content>[^<>/]+)\.ascx";
                match = Regex.Match(this.DesignSkin.Url, pattern, options);
                if (match.Success)
                    this.Skin = match.Groups["content"].Value.Trim();
            }

            pattern = string.Format(contentPattern, "bodyContent");
            match = Regex.Match(this.Content, pattern, options);
            if (match.Success)
            {
                this.DesignLayout = new ControlLoaderInfo(this, this);
                this.DesignLayout.Deserialize(match.Groups["content"].Value.Trim());
                pattern = @"~/Layouts/(?<content>[^<>/]+)/[^<>/]+\.ascx";
                match = Regex.Match(this.DesignLayout.Url, pattern, options);
                if (match.Success)
                    this.Layout = match.Groups["content"].Value.Trim();
                pattern = @"~/Layouts/[^<>/]+/(?<content>[^<>/]+)\.ascx";
                match = Regex.Match(this.DesignLayout.Url, pattern, options);
                if (match.Success)
                    this.PageTemplate = match.Groups["content"].Value.Trim();
            }
        }

        #endregion

        public class PageInfoMetaData
        {
            [VitData.DisplayName("PageInfo.Name")]
            [VitData.Required()]
            [VitData.StringLength(50)]
            public string Name { get; set; }
            [VitData.DisplayName("PageInfo.Title")]
            [VitData.Description("PageInfo.Title.Description")]
            [VitData.Required()]
            [VitData.StringLength(50)]
            public string Title { get; set; }
            [VitData.DisplayName("PageInfo.MetaKeywords")]
            [VitData.Description("PageInfo.MetaKeywords.Description")]
            public string MetaKeywords { get; set; }
            [VitData.DisplayName("PageInfo.MetaDescription")]
            [VitData.Description("PageInfo.MetaDescription.Description")]
            public string MetaDescription { get; set; }

            [VitData.DisplayName("PageInfo.Layout")]
            [UIHint("Layout")]
            public ControlLoaderInfo DesignLayout { get; set; }
            [VitData.DisplayName("PageInfo.Skin")]
            [UIHint("Skin")]
            public ControlLoaderInfo DesignSkin { get; set; }

            [ScaffoldColumn(false)]
            public string Layout { get; set; }
            [ScaffoldColumn(false)]
            public string Skin { get; set; }
            [VitData.DisplayName("PageInfo.PageTemplate")]
            [ScaffoldColumn(false)]
            public string PageTemplate { get; set; }

            [ScaffoldColumn(false)]
            public string Content { get; set; }
            [ScaffoldColumn(false)]
            public string FilePath { get; set; }
        }
    }
}
